<? 

//	****************************************
//	SbSE auth functions v0.9.12 / 2012.04.03
//	****************************************

$PRIV = array(
//	'edit-allowed'							=> array('mask' => 0x0001, 'name' => 'Edit allowed'),
	'admin'					=> array('mask' => 0x0010, 'name' => 'Access to admin area'),	// *** need to be syncronized with const
);

define('UNIQUE', 'D0Y0ULlK3CO0K13S');

if (defined('USE_LOG4')) {
	if (USE_LOG4) {
		include('_lib/log4php/Logger.php');
		Logger::configure('_lib/_log.xml');	 
		$GLOBALS['log'] = Logger::getLogger("default");
	}
} else define('USE_LOG4', false);

function get_priv_mask() {	//calculate page tag bits that corresponds to privileges
	global $PRIV;
	$temp = 0;
	foreach ($PRIV as $nm => $v) $temp |= $v['mask'];
	return $temp;
}

function check_priv() {	// check if user have all required privileges to access this page
	global $DATA;
	$mask = get_priv_mask();
	$need = $DATA['page']['tag'] & $mask;
	return (($need & user_info('priv',0)) == $need);
}

function priv($p_value) {	// check if user have some privilegies
	global $PRIV;
	return (session_exists() && isset($PRIV[$p_value]) && isset($_SESSION['user'])) ? (($_SESSION['user']['priv'] & $PRIV[$p_value]['mask']) == $PRIV[$p_value]['mask']) : false;
}

function user_info($p, $def='') {
	return (session_exists() && isset($_SESSION['user'][$p])) ? $_SESSION['user'][$p] : $def;
}

function get_global($p, $def='') {
	return (session_exists() && isset($_SESSION['globals'][$p])) ? $_SESSION['globals'][$p] : $def;
}

function set_global($p, $v, $store = true) {
	$_SESSION['globals'][$p] = $v;
	
	if ($store) {
		set_settings('globals', $_SESSION['globals']);
		store_settings();
	}
}

function get_settings($p, $def='') {
	return (session_exists() && isset($_SESSION['user']['settings'][$p])) ? $_SESSION['user']['settings'][$p] : $def;
}

function set_settings($p, $v) {
	$_SESSION['user']['settings'][$p] = $v;
}

function store_settings() {
	if (session_exists() && $id = logged_in()) {
		dataset('db_update', tb('auth'), array('settings' => php2js($_SESSION['user']['settings'])), "id=$id");
	}
}

function logged_in() {
	return (int)user_info('id', 0);
}

function pwd($p, $l = '') { return md5($p.UNIQUE.$l); }

function filterData() {
	$map = array(
		'see-unseen' => array('present' => '', 'absent' => ' AND (!field & '.AA_UNSEEN.' = 0)'),
	);
	
	$temp = array();
	foreach($map as $id => $v)
		if ($m = $v[permitted($id) ? 'present' : 'absent'])
			$temp[] = $m;
			
	return implode('', $temp);
}

function ac($options = array()) {
	$o = array_extend(array('field' => 'attr'), (array)$options);
	$d = filterData();
	$t = array();
	switch(gettype($o['field'])) {
		case 'string':
			$t[] = str_replace('!field', $o['field'], $d);
			break;
			
		case 'array':
			foreach($o['field'] as $f)
				$t[] = str_replace('!field', $f, $d);
			break;
	}
	return implode(' ', $t);
}

function session_exists() { return isset($_COOKIE[$GLOBALS['SESSION_NAME']]) || isset($_POST[$GLOBALS['SESSION_NAME']]); }

function create_anonymous() {
	return array(
		'id' => 0,
		'name' => 'Not logged in yet',
		'attr' => 0, 
		'login' => 'anonymous',
		'priv' => 0,
		'time' => date("H:i"),
		'settings' => array(),
	); 
}

function create_session($user = false) {
	session_name($GLOBALS['SESSION_NAME']);
	
	if (($sid = $_POST[$GLOBALS['SESSION_NAME']]) && (strlen($sid) > 32)) {
		$p = substr($sid, 0, strlen($sid) - 32);
		if ($sid == $p.pwd($p))
			session_id($p);
	}
	
	session_start();

	if (!is_array($_SESSION) || !isset($_SESSION['user'])) {
		
		$_SESSION = array();
		$_SESSION['user'] = is_array($user) ? $user : create_anonymous();
		include '_lib/_session.php';
	} else {
		if (is_array($user)) {
			$_SESSION['user'] = $user;
			include '_lib/_session.php';
		}
	}
	
	$_SESSION['globals'] = get_settings('globals', array());
}

/*** RBAC ***/

function loadPerm($page = 0) {
	global $DATA;
	
	if (!$page) $page = $DATA['page']['id'];
	$u = logged_in();
	
	if (MC && ($t = mc("auth.perm.$u.$page")))
		return $t;	// got from Memcached
	

	$t = $u ? 
		datafetch_array('db_list', array(
			'table' => tb('sec_obj, sec_role, sec_sess, sec_perm'), 
			'where' => "sec_sess.id_user=$u AND 
				sec_sess.id_role=sec_role.id AND 
				sec_perm.id_role=sec_role.id AND 
				sec_perm.id_obj=sec_obj.id AND 
				sec_perm.id_parent in (0,$page)", 
			'select' => 'sec_perm.id as id, sec_obj.name as perm, sec_role.name as role',
			'index' => 'perm')) :

		datafetch_array('db_list', array(
			'table' => tb('sec_obj, sec_role, sec_sess, sec_perm'), 
			'where' => dbAndL('sec_role.attr', RO_DEFAULT)." AND
				sec_perm.id_role=sec_role.id AND 
				sec_perm.id_obj=sec_obj.id AND 
				sec_perm.id_parent in (0,$page)", 
			'select' => 'sec_perm.id as id, sec_obj.name as perm, sec_role.name as role',
			'index' => 'perm'));
			
//	if (MC) $x = $GLOBALS['mc']->set(MC_PREFIX."auth.perm.$u.$page", $t, MC_EXPIRE - mt_rand(2*60, 7*60));
	mcSet("auth.perm.$u.$page", $t, MC_EXPIRE - mt_rand(2*60, 7*60));

//debug($x ? 'stored' : 'not stored');
//debug($GLOBALS['mc']->getResultMessage());
	return $t;
}


function loadPermissions() {
	global $DATA;
	$res = logged_in() ? $_SESSION['user'] : create_anonymous();
	$res['perm'] = loadPerm();
	return $DATA['user'] = $res;
}

function permitted($perm, $page = 0) {
	global $DATA;
	if ($page) {
		$p = loadPerm($page);
		return isset($p[$perm]);
	} else
	return isset($DATA['user']['perm'][$perm]);
}

function readyPermissions() {
	return isset($GLOBALS['DATA']['user']);
}

//*********************************************************************************************************

$SESSION_NAME = 'sid';

if (session_exists() || PERMANENT_SESSION) create_session();